home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
dev
/
c
/
vbcc.lha
/
vbcc
/
ic.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-02-17
|
52KB
|
1,467 lines
/* $VER: vbcc (ic.c) V0.4 */
#include "vbc.h"
static char FILE_[]=__FILE__;
int do_arith(np,struct IC *,np,struct obj *);
void gen_test(struct obj *o,int t,int branch,int label)
/* Generiert ein test o, branch label und passt auf, dass */
/* kein TEST const generiert wird. */
{
struct IC *new;
if(o->flags&KONST){
eval_const(&o->val,t);
if(zdeqto(vdouble,d2zd(0.0))&&zleqto(vlong,l2zl(0L))&&zuleqto(vulong,ul2zul(0UL))){
if(branch==BEQ) branch=BRA; else branch=0;
}else{
if(branch==BNE) branch=BRA; else branch=0;
}
}else{
new=mymalloc(ICS);
new->code=TEST;
new->q2.flags=new->z.flags=0;
new->typf=t;
new->q1=*o;
add_IC(new);
}
if(branch){
new=mymalloc(ICS);
new->code=branch;
new->typf=label;
add_IC(new);
}
}
void inline_memcpy(np z,np q,zlong size)
/* fuegt ein ASSIGN-IC ein, das memcpy(z,q,size) entspricht */
{
struct IC *new=mymalloc(ICS);
if((z->ntyp->flags&NQ)!=POINTER) ierror(0);
if((q->ntyp->flags&NQ)!=POINTER) ierror(0);
gen_IC(z,0,0);
if(z->o.flags&DREFOBJ){
struct IC *n2=mymalloc(ICS);
n2->code=ASSIGN;
n2->typf=q->ntyp->flags;
n2->q1=z->o;
get_scratch(&n2->z,z->ntyp->flags,z->ntyp->next->flags,z->ntyp);
n2->q2.flags=0;
n2->q2.val.vlong=sizetab[POINTER];
new->z=n2->z;
add_IC(n2);
}else{
new->z=z->o;
}
if(new->z.flags&VARADR) new->z.flags&=~VARADR; else new->z.flags|=DREFOBJ;
gen_IC(q,0,0);
if(q->o.flags&DREFOBJ){
struct IC *n2=mymalloc(ICS);
n2->code=ASSIGN;
n2->typf=q->ntyp->flags;
n2->q1=q->o;
get_scratch(&n2->z,q->ntyp->flags,q->ntyp->next->flags,q->ntyp);
n2->q2.flags=0;
n2->q2.val.vlong=sizetab[POINTER];
new->q1=n2->z;
add_IC(n2);
}else{
new->q1=q->o;
}
if(new->q1.flags&VARADR) new->q1.flags&=~VARADR; else new->q1.flags|=DREFOBJ;
new->code=ASSIGN;
new->typf=UNSIGNED|CHAR;
new->q2.flags=0;
new->q2.val.vlong=size;
add_IC(new);
}
void add_IC(struct IC *new)
/* fuegt ein IC ein */
{
int code;
if(!new) return;
if(nocode) {free(new);return;}
new->next=0;
new->q1.am=new->q2.am=new->z.am=0;
new->line=line; new->file=0;
code=new->code;
if(code>=BEQ&&code<=BRA) new->q1.flags=new->q2.flags=new->z.flags=0;
if(code==ALLOCREG||code==FREEREG||code==SAVEREGS||code==RESTOREREGS) new->typf=0;
if(DEBUG&64){ pric(stdout,first_ic);printf("new\n");pric2(stdout,new);printf("-\n");}
if(new->q1.flags&VAR){
if(!new->q1.v) ierror(0);
new->q1.v->flags|=USEDASSOURCE;
if(code==ADDRESS||(new->q1.flags&VARADR)) new->q1.v->flags|=USEDASADR;
new->q1.v->priority+=currentpri;
}
if(new->q2.flags&VAR){
if(!new->q2.v) ierror(0);
new->q2.v->flags|=USEDASSOURCE;
if(code==ADDRESS||(new->q2.flags&VARADR)) new->q2.v->flags|=USEDASADR;
new->q2.v->priority+=currentpri;
}
if(new->z.flags&VAR){
if(!new->z.v) ierror(0);
if(new->z.flags&DREFOBJ) new->z.v->flags|=USEDASSOURCE; else new->z.v->flags|=USEDASDEST;
new->z.v->priority+=currentpri;
}
if(/*(c_flags_val[0].l&2)&&*/code==LABEL){
/* entfernt Spruenge zu direkt folgenden Labels */
struct IC *p=last_ic;
while(p){
if(p->typf==new->typf&&p->code>=BEQ&&p->code<=BRA){
struct IC *n;
if(DEBUG&1) printf("%s l%d deleted\n",ename[p->code],p->typf);
n=p->next;
remove_IC(p);
p=n;
}else{
if(p->code!=LABEL) break;
p=p->prev;
}
}
}
if(last_ic){
if(code==ASSIGN){
if((last_ic->z.flags&(REG|SCRATCH|DREFOBJ))==(REG|SCRATCH)&&(new->q1.flags==last_ic->z.flags)&&last_ic->z.reg==new->q1.reg/*&&last_ic->code!=CALL*/){
if(USEQ2ASZ||!(last_ic->q2.flags®)||!(new->z.flags®)||last_ic->q2.reg!=new->z.reg){
if(USEQ2ASZ||!(last_ic->q2.flags&VAR)||!(new->z.flags&VAR)||last_ic->q2.v!=new->z.v){
/* verbindet op a,b->reg,move reg->c zu op a,b->c */
/* hier fehlt aber noch Registerfreigabe */
last_ic->z=new->z;
if(DEBUG&1) printf("move and op combined\n");
if((new->q1.flags&SCRATCH)&&(new->q1.reg!=new->z.reg||!(new->z.flags®)))
free_reg(new->q1.reg);
free(new);
return;
}
}
}
if((last_ic->z.flags&(VAR|SCRATCH|DREFOBJ))==(VAR|SCRATCH)&&(new->q1.flags==last_ic->z.flags)&&last_ic->z.v==new->q1.v/*&&last_ic->code!=CALL*/){
if(USEQ2ASZ||!(last_ic->q2.flags®)||!(new->z.flags®)||last_ic->q2.reg!=new->z.reg){
if(USEQ2ASZ||!(last_ic->q2.flags&VAR)||!(new->z.flags&VAR)||last_ic->q2.v!=new->z.v){
/* verbindet op a,b->scratch,move scratch->c zu op a,b->c */
/* hier fehlt aber noch Registerfreigabe */
last_ic->z=new->z;
if(DEBUG&1) printf("move and op combined(2)\n");
/* if((new->q1.flags&SCRATCH)&&(new->q1.reg!=new->z.reg||!(new->z.flags®)))
free_reg(new->q1.reg);*/
free(new);
return;
}
}
}
}
if(last_ic->code==BRA){
if(code!=LABEL&&code!=ALLOCREG&&code!=FREEREG){
/* loescht alles nach bra bis ein Label kommt */
/* momentan noch nicht perfekt, da es bei alloc/freereg stoppt */
free(new);
if(DEBUG&1) printf("Unreachable Statement deleted\n");
return;
}
if(last_ic->prev&&code==LABEL){
/* ersetzt bcc l1;bra l2;l1 durch b!cc l2 */
if(last_ic->prev->code>=BEQ&&last_ic->prev->code<=BGT&&new->typf==last_ic->prev->typf){
if(DEBUG&1) printf("%s l%d;%s l%d; substituted\n",ename[last_ic->prev->code],last_ic->prev->typf,ename[last_ic->code],last_ic->typf);
if(last_ic->prev->code&1) last_ic->prev->code--;
else last_ic->prev->code++;
last_ic->prev->typf=last_ic->typf;
last_ic=last_ic->prev;
free(last_ic->next);
last_ic->next=new;new->prev=last_ic;
last_ic=new;
return;
}
}
}
/* }*/
new->prev=last_ic;
last_ic->next=new;
last_ic=new;
}else{
last_ic=new;first_ic=new;new->prev=0;
}
ic_count++;
/* Merken, on Fliesskomma benutzt wurde */
if(code!=LABEL&&(code<BEQ||code>BRA)){
if((new->typf&NQ)==FLOAT||(new->typf&NQ)==DOUBLE) float_used=1;
if(code==CONVFLOAT||code==CONVDOUBLE) float_used=1;
}
if((new->q1.flags&SCRATCH)&&(new->q1.reg!=new->z.reg||!(new->z.flags®)))
free_reg(new->q1.reg);
if((new->q2.flags&SCRATCH)&&(new->q2.reg!=new->z.reg||!(new->z.flags®)))
free_reg(new->q2.reg);
}
void gen_IC(np p,int ltrue,int lfalse)
/* Erzeugt eine IC-Liste aus einer expression */
{
struct IC *new; struct regargs_list *rl;
if(!p) return;
if(p->flags==STRING){
/* hier fehlt noch die Verwaltung der String-Inhalte */
p->o.v=add_var(empty,clone_typ(p->ntyp),STATIC,p->cl);
p->o.v->flags|=DEFINED;
p->o.flags=VAR;
p->o.reg=0;
p->o.val=p->val;
return;
}
if(p->flags==IDENTIFIER){
/* p->o.v=find_var(p->identifier,0);*/
p->o.flags=VAR;
p->o.reg=0;
p->o.val=p->val;
return;
}